package cn.tedu.csmallproducts.service.impl;
import cn.tedu.csmallproducts.ex.ServiceException;
import cn.tedu.csmallproducts.mapper.CategoryMapper;
import cn.tedu.csmallproducts.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmallproducts.pojo.dto.CategoryUpdateDTO;
import cn.tedu.csmallproducts.pojo.entity.Album;
import cn.tedu.csmallproducts.pojo.entity.Category;
import cn.tedu.csmallproducts.pojo.vo.AlbumStandardVO;
import cn.tedu.csmallproducts.pojo.vo.CategoryListItemVO;
import cn.tedu.csmallproducts.pojo.vo.CategoryStandardVO;
import cn.tedu.csmallproducts.service.ICategoryService;
import cn.tedu.csmallproducts.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Slf4j
@Service
public class CategoryServiceImpl implements ICategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        log.error("参数:{}",categoryAddNewDTO);
        // 调用参数对象的getName()得到尝试添加的类别的名称
        String name = categoryAddNewDTO.getName();
        // 调用Mapper对象的countByName()执行统计查询
        int count = categoryMapper.countByName(name);
        log.debug("根据名称【{}】统计数量，结果：{}", name, count);
        // 判断统计结果是否大于0
        if (count > 0) {
            // 是：名称被占用，抛出异常
            String message = "添加类别失败，类别名称已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        // 通过参数对象获取parentId
        Long parentId = categoryAddNewDTO.getParentId();
        // 预设depth为1
        Integer depth =1;
        CategoryStandardVO parentCategory = null;
        if (parentId != 0) {
            // 否：调用Mapper对象的getStandardById()查询父级类别
            parentCategory = categoryMapper.getStandardById(parentId);
            log.debug("ffff{}",parentCategory);
            //      判断查询结果（父级类别）是否为null
            if (parentCategory == null) {
                //      是：抛出异常
                String message = "添加类别失败，父级类别不存在！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
            } else {
                //      否：depth（深度值）为：父级类别的depth + 1
                depth = parentCategory.getDepth()+1;
            }
        }

        // 创建Category对象
        Category category = new Category();
        // 复制属性
        BeanUtils.copyProperties(categoryAddNewDTO, category);
        // 补全Category对象的属性值：depth >>>
        category.setDepth(depth);
        // 补全Category对象的属性值：isParent >>> 固定为0
        category.setIsParent(0);
        // 调用Mapper对象的insert()方法执行插入
        int rows = categoryMapper.insert(category);
        if (rows != 1) {
            String message = "添加类别失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }

        // 判断parentId是否不为0，并判断父级类别的isParent是否为0
        if (parentId != 0 && parentCategory.getIsParent() == 0) {
            // 是：将父级类别的isParent更新为1
            Category updateParentCategory = new Category();
            updateParentCategory.setId(parentId);
            updateParentCategory.setIsParent(1);
            rows = categoryMapper.update(updateParentCategory);
            if(rows!=1){
                String message = "修改类别失败，服务器忙，请稍后再尝试！";
                log.warn(message);
                throw  new ServiceException(ServiceCode.ERROR_UPDATE,message);
            }
        }
    }

    // TODO 删除业务规则：当存在子级类别（当前类别isParent为1）时，不允许删除
    // TODO 删除业务规则：当所有子级类别全部被删除时，isParent需要从1更新为0
    @Override
    public void delete(Long id) {
        // 调用Mapper对象的getStandardById()执行查询
        CategoryStandardVO currentCategory = categoryMapper.getStandardById(id);
        log.debug("【根据ID查询到类别对象{}】",currentCategory);
        // 判断查询结果是否为null，如果是，则抛出异常
        if (currentCategory == null) {
            // 是：数据不存在，抛出异常
            String message = "删除类别失败，尝试删除的类别数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        // 判断查询结果中的isParent是否为1，如果是，则抛出异常
        if (currentCategory.getIsParent() == 1) {
            String message = "删除类别失败，该类别仍包含子级类别！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        // 调用Mapper对象的deleteById()方法执行删除
        int rows = categoryMapper.deleteById(id);
        log.debug("【删除类别对象数量{}】",rows);
        if (rows != 1) {
            String message = "删除类别失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE, message);
        }

        // 调用Mapper对象的countByParentId方法，根据以上查询结果中的parentId，执行统计
        Long parentId = currentCategory.getParentId();
        log.debug("【类别对象的父级ID{}】",parentId);
        int count = categoryMapper.countByParentId(parentId);
        log.debug("【类别对象的父级ID数量{}】",count);
        // 判断统计结果为0，则将父级类别的isParent更新为0
        if (count == 0) {
            Category parentCategory = new Category();
            parentCategory.setId(parentId);
            parentCategory.setIsParent(0);
            rows = categoryMapper.update(parentCategory);
            if (rows != 1) {
                String message = "删除类别失败，服务器忙，请稍后再尝试！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
            }
        }
    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id, 1);
    }

    @Override
    public void setDisable(Long id) {
        updateEnableById(id, 0);
    }


    @Override
    public List<CategoryListItemVO> listByParentId(Long parentId) {
            log.debug("开始处理【根据父级类别查询子级类别列表】的业务，参数：{}", parentId);
            List<CategoryListItemVO> list = categoryMapper.listByParentId(parentId);
            return list;
    }

    private void updateEnableById(Long id, Integer enable) {
        // 调用Mapper对象的getStandardById()方法执行查询
        CategoryStandardVO currentCategory = categoryMapper.getStandardById(id);
        // 判断查询结果是否为null，如果是，则抛出异常
        if (currentCategory == null) {
            String message = ENABLE_TEXT[enable] + "类别失败，类别数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        // 判断查询结果中的enable与参数enable是否相同，如果是，则抛出异常（当前状态与目标状态相同，没必要执行更新）
        if (currentCategory.getEnable() == enable) {
            String message = ENABLE_TEXT[enable] + "类别失败，此类别已经处于" + ENABLE_TEXT[enable] + "状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        // 创建Category对象
        Category updateCategory = new Category();
        // 向Category对象中封装属性值：id, enable，均来自方法参数
        updateCategory.setId(id);
        updateCategory.setEnable(enable);
        // 调用Mapper对象的update()方法执行更新
        int rows = categoryMapper.update(updateCategory);
        if (rows != 1) {
            String message = ENABLE_TEXT[enable] + "类别失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public void setDisplay(Long id) {
        updateDisplayById(id, 1);
    }

    @Override
    public void setBLANK(Long id) {
        updateDisplayById(id, 0);
    }

    private void updateDisplayById(Long id, Integer display) {
        // 调用Mapper对象的getStandardById()方法执行查询
        CategoryStandardVO currentCategory = categoryMapper.getStandardById(id);
        // 判断查询结果是否为null，如果是，则抛出异常
        if (currentCategory == null) {
            String message = DISPLAY_TEXT[display] + "在导航栏失败，类别数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        // 判断查询结果中的display与参数display是否相同，如果是，则抛出异常（当前状态与目标状态相同，没必要执行更新）
        if (currentCategory.getIsDisplay() == display) {
            String message =DISPLAY_TEXT[display] + "在导航栏失败，此类别已经处于" + DISPLAY_TEXT[display] + "状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        // 创建Category对象
        Category updateCategory = new Category();
        // 向Category对象中封装属性值：id, display，均来自方法参数
        updateCategory.setId(id);
        updateCategory.setIsDisplay(display);
        // 调用Mapper对象的update()方法执行更新
        int rows = categoryMapper.update(updateCategory);
        if (rows != 1) {
            String message = DISPLAY_TEXT[display] + "在导航栏失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public CategoryStandardVO getStandardById(Long id) {
        log.debug("开始处理【根据ID查询类别详情】的业务，参数：{}", id);
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        if(queryResult==null){
            String message = "查询类别详情失败，相册数据不存在！";
            log.warn(message);
            throw  new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }
        return queryResult;
    }

    @Override
    public void updateInfoById(Long id, CategoryUpdateDTO categoryUpdateDTO) {
        log.debug("开始处理【修改类别详情】的业务，ID：{}，新数据：{}", id, categoryUpdateDTO);
        // 调用Mapper对象的getStandardById()执行查询
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        // 判断查询结果是否为null
        if (queryResult == null) {
            // 是：抛出异常
            String message = "修改类别详情失败，尝试修改的类别数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        // 调用Mapper对象的countByNameAndNotId()执行统计
        int count = categoryMapper.countByNameAndNotId(id, categoryUpdateDTO.getName());
        // 判断统计结果是否大于0
        if (count > 0) {
            // 是：名称被占用，抛出异常
            String message = "修改类别详情失败，类别名称已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        // 创建Category对象
        Category category = new Category();
        // 复制属性，设置ID
        BeanUtils.copyProperties(categoryUpdateDTO, category);
        category.setId(id);
        // 调用Mapper对象的update()方法执行修改
        int rows = categoryMapper.update(category);
        if (rows != 1) {
            String message = "修改类别详情失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }
}
